Skip to content

refactor(ios): replace segmented Picker with TabView(.sidebarAdaptable) architecture#859

Merged
datlechin merged 10 commits intomainfrom
refactor/ios-tabview-architecture
Apr 25, 2026
Merged

refactor(ios): replace segmented Picker with TabView(.sidebarAdaptable) architecture#859
datlechin merged 10 commits intomainfrom
refactor/ios-tabview-architecture

Conversation

@datlechin
Copy link
Copy Markdown
Collaborator

Summary

  • TabView(.sidebarAdaptable) replaces the segmented Picker in ConnectedView — 4 tabs (Tables, Query, History, Settings), each with its own NavigationStack. Tab bar on iPhone, sidebar on iPad.
  • ConnectionCoordinator extracted from the 455-line ConnectedView — @Observable class owning all connection lifecycle (connect, reconnect, switch DB/schema), table loading, and query history. Injected via .environment() to eliminate prop drilling (18 parameters across 3 views reduced to 0).
  • QueryHistoryView promoted from a sheet inside QueryEditorView to a dedicated tab. Cross-tab communication via coordinator.pendingQuery + tab switch.
  • FilterSheetView + RowCard extracted from the 910-line DataBrowserView into standalone component files.
  • Deep link table navigation — Handoff viewTable now navigates to the specific table via NavigationStack(path:), not just the connection.
  • iOS 18 minimum deployment target for sidebarAdaptable support.

Architecture (before → after)

BEFORE:
ConnectionListView → NavigationStack → ConnectedView (Picker) → shared stack

AFTER:
ConnectionListView → ConnectedView → TabView(.sidebarAdaptable)
  ├── Tab "Tables"   → NavigationStack(path:) → TableListView → DataBrowserView
  ├── Tab "Query"    → NavigationStack → QueryEditorView
  ├── Tab "History"  → NavigationStack → QueryHistoryView
  └── Tab "Settings" → NavigationStack → SettingsView

Key metrics

Before After
ConnectedView 455 lines 148 lines (-68%)
DataBrowserView 910 lines 690 lines (-24%)
Prop drilling params 18 across 3 views 0 (@Environment)
NavigationStacks 1 shared 4 independent
Tab state preservation No (lost on switch) Yes (SwiftUI native)

Test plan

  • Build TableProMobile scheme targeting iOS 18 simulator
  • Connect to a database — 4-tab bar appears at bottom (iPhone) or sidebar (iPad)
  • Switch between Tables and Query tabs — verify each preserves navigation state independently
  • Drill into Tables → DataBrowserView → RowDetailView, switch to Query, switch back — should return to RowDetailView, not table list
  • Tap a history item in History tab — should load query into editor and switch to Query tab
  • Test database switcher menu in Tables tab toolbar (MySQL/PostgreSQL with multiple databases)
  • Test schema switcher menu in Tables tab toolbar (PostgreSQL)
  • Background the app and return — verify reconnection works
  • Switch between connections in sidebar — verify old coordinator is destroyed, new one created
  • Keyboard shortcuts Cmd+1-4 on iPad with hardware keyboard
  • Verify Settings tab works (same content as before, now a tab instead of sheet)
  • iPad: verify tab bar transforms to sidebar with expand/collapse

…plitView

- Replace per-tab NavigationStack with single NavigationStack wrapping TabView
- Move toolbar and navigationDestination to NavigationStack level
- Cache coordinators in ConnectionListView to preserve state across navigations
- Load databases/schemas before setting phase to prevent toolbar flicker
- Remove .tabViewStyle(.sidebarAdaptable) which blocked navigation preferences
- Fix CHANGELOG to match final architecture (no sidebarAdaptable)
- Remove redundant internal modifier on ConnectedTab
- Fix navigateToPendingTable race between tab switch and path append
- Evict coordinator cache on connection deletion
@datlechin datlechin merged commit 726aadc into main Apr 25, 2026
2 checks passed
@datlechin datlechin deleted the refactor/ios-tabview-architecture branch April 25, 2026 16:05
@datlechin datlechin restored the refactor/ios-tabview-architecture branch April 25, 2026 16:31
@datlechin datlechin deleted the refactor/ios-tabview-architecture branch April 25, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant